package com.vertx.core.annotation.data.explain;

import com.vertx.core.annotation.base.ClassAnnotationExplain;
import com.vertx.core.annotation.data.Address;
import com.vertx.core.annotation.data.Query;
import com.vertx.core.beam.AbstractBeanFactory;
import com.vertx.core.beam.BeanContainer;
import com.vertx.core.constant.Constant;
import com.vertx.core.exception.AnnotationExplainUnMatchedException;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import org.apache.log4j.Logger;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 描述:
 * 创建人:hzw
 * 创建时间: 2018/4/18 17:38
 **/
public class QueryAnnotationExplain implements ClassAnnotationExplain {

    private static final Logger logger = Logger.getLogger(QueryAnnotationExplain.class);

    @Override
    public void handler(Class classes, Annotation annotation, AbstractBeanFactory beanFactory, Object[] params) throws Exception {
        Vertx vertx=(Vertx)params[0];
        String consumerName;
        boolean bus;
        if(annotation instanceof Query){
            Query query=(Query)annotation;
            consumerName=query.name();
            bus=query.bus();
        }else{
            logger.error("Query注解解释器不匹配");
            throw new AnnotationExplainUnMatchedException("Query注解注解解释器不匹配");
        }
        BeanContainer beanContainer = new BeanContainer(classes);
        if (consumerName.length() > 0) {
            //如果注册bean的时候指定了名称，就使用指定的名称
            beanContainer.setBeanName(consumerName);
        } else {
            beanContainer.setBeanName(beanFactory.getSimpleClassName(classes));
        }
        beanFactory.registerBean(beanContainer.getBeanName(), beanContainer);
        logger.debug("Query is register: " + beanContainer.getBeanName());
        if(bus){//发送
            vertx.eventBus().consumer(consumerName,res->{
                JsonObject json=(JsonObject)res.body();
                String key=json.getString("key");
                Method h=null;
                Method[] methods=classes.getMethods();
                for (Method method : methods) {
                    Address address=method.getAnnotation(Address.class);
                    if(null!=address){//存在此注解
                        if(address.path().equals(key)){
                            h=method;
                            break;
                        }
                    }
                }
                if(null==h){//没有找到方法
                    JsonObject reply=new JsonObject();
                    reply.put("code",Constant.RECEIVE_FAIL);
                    reply.put("message","没有找到方法"+key);
                    res.reply(reply);
                    logger.error("没有找到方法"+key);
                }else{
                    try{
                        h.invoke(classes.newInstance(),new Object[]{json,res});
                    }catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException
                            | InstantiationException e){
                        logger.error("出现未知异常"+e.getMessage());
                        JsonObject reply=new JsonObject();
                        reply.put("code",Constant.RECEIVE_FAIL);
                        reply.put("message","出现未知异常"+key);
                        res.reply(reply);
                    }
                }
            });
        }
    }

    @Override
    public Annotation getExplainClass() {
        return ()->Query.class;
    }
}
